<template>
  <div>
    <el-upload
        class="upload-main"
        v-model:file-list="fileList"
        list-type="picture-card"
        :data="{ fileType: Upload.FILETYPE.IMAGE, type: props.uploadType }"
        :headers="{ loginToken, appKey, timestamp, randomId, appSign}"
        :action="Upload.URL"
        :before-upload="beforeUpload"
        :on-change="handleUpload"
        :on-remove="handleRemoveImg"
        :on-preview="handlePreview"
        :multiple="props.style.multiple"
        :class="{disabled: uploadDisabled}"
        :style="{'--width': props.style.width, '--height': props.style.height}"
    >
      <div class="upload">
        <el-icon><Plus /></el-icon>
        <div style="font-size: 12px">上传</div>
      </div>
    </el-upload>
    <el-dialog v-model="previewVisible" @close="handleCancel" width="600" :append-to-body="true">
      <img alt="example" style="width: 100%" :src="previewImage" />
    </el-dialog>
  </div>
</template>

<script setup name="ImgUpload">

import useCurrentInstance from "@/hooks/useCurrentInstance";
import {Upload} from "@/common/constant";
import {CacheUtil} from "@/utils/cacheUtil";
import {Plus} from "@element-plus/icons-vue";
import {AppSign} from "@/utils/appSign.js";

const {proxy} = useCurrentInstance();
const fileList = ref([]);
const loginToken = CacheUtil.getToken();
const appKey = import.meta.env.VITE_APP_KEY;
const timestamp = new Date().getTime();
const randomId = Math.random().toString(36).substring(2, 10);
const appSign = AppSign.getAppSign(timestamp, randomId, appKey);
const loading = ref(false);
const previewVisible = ref(false);
const previewImage = ref('');
const emits = defineEmits(["uploadSuccess", "removeImg"])
const uploadDisabled = ref(true);
const props = defineProps({
  fileType: {
    type: [String,Number],
    required: false
  },
  filePath: {
    type: String,
    required: false
  },
  filePaths: {
    type: Array,
    required: false
  },
  uploadType: {
    type: String,
    required: true
  },
  style: {
    type: Object,
    required: false,
    default: () => {
      return {
        width: '146px',
        height: '146px',
        multiple: false
      }
    }
  }
})

//上传图片前处理方法
const beforeUpload = (file) => {
  const isJpgOrPng = /^image\/(jpeg|png|jpg)$/.test(file.type);
  if (!isJpgOrPng) {
    proxy.$message.error('只能上传 JPG/PNG 格式的图片!');
  }
  const isLt2M = file.size / 1024 / 1024 < 10;
  if (!isLt2M) {
    proxy.$message.error('图片大小不能超过 10MB!');
  }
  return isJpgOrPng && isLt2M;
}
function handleRemoveImg(uploadFile, uploadFiles) {
  if (props.style.multiple) {
    fileList.value = uploadFiles;
    emits("removeImg", props.fileType, fileList.value);
  } else {
    fileList.value = [];
    emits("removeImg", props.fileType);
  }
  uploadDisabled.value = false;
}
function handleUpload(info) {
  if (info.status === 'uploading') {
    loading.value = false;
    return;
  }
  if (info.status === 'success') {
    if (info.response.success) {
      if (props.style.multiple) {
        const urls = fileList.value.map((file) => {
          return {
            name: file.name,
            url: file.response.data.filePath,
          }
        })
        emits("uploadSuccess", urls, props.fileType)
      } else {
        fileList.value = [{name: info.name, url: info.response.data.filePath}];
        emits("uploadSuccess", info.response.data.filePath, props.fileType);
      }
    } else {
      proxy.$message.error(info.response.message);
      fileList.value = [];
    }
  }
  if (info.status === 'fail') {
    proxy.$message.error('upload error');
    fileList.value = [];
  }
  loading.value = false;
  uploadDisabled.value = true;
}

function handleCancel() {
  previewVisible.value = false;
}
function handlePreview(file) {
  previewImage.value = file.url;
  previewVisible.value = true;
}
function resetData() {
  fileList.value = [];
  emits("removeImg", props.fileType);
}
watch(() => props.filePath, v => {
      if(v) {
        fileList.value = [{
          name: 'image.png',
          url: props.filePath
        }];
      }
    },
    {immediate: true, deep: true}
)

watch(() => props.filePaths, v => {
  if (!fileList.value && fileList.value.length === 0) {
    fileList.value = v;
  }
})

watch(fileList, (newVal) => {
  uploadDisabled.value = !props.style.multiple && newVal.length === 1;
}, {
  deep: true,
  immediate: true
})

onMounted(() => {
  if (props.filePaths && props.filePaths.length > 0) {
    fileList.value = props.filePaths;
  }
})
defineExpose({
  resetData
})

</script>

<style scoped lang="scss">
.upload {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column
}
.disabled :deep(.el-upload--picture-card) {
  display: none !important;
}

:deep(.el-upload--picture-card) {
  width: var(--width);
  height: var(--height);
}

:deep(.el-upload-list--picture-card .el-upload-list__item) {
  width: var(--width);
  height: var(--height);
}
:deep(.el-upload-list__item .el-icon--close-tip) {
  display: none !important;
}
:deep(.el-upload-list__item.is-success .el-upload-list__item-status-label) {
  display: none !important;
}
</style>